package qc.module.ehs.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import qc.common.core.exception.QCPromptException;
import qc.common.core.unify.QCUnifyReturnValue;
import qc.common.core.utils.DateUtil;
import qc.common.core.utils.IdentifierUtil;
import qc.module.ehs.dto.checkrecord.CheckRecordDto;
import qc.module.ehs.dto.checkrecord.CheckRecordSaveResultDto;
import qc.module.ehs.dto.taskexecute.*;
import qc.module.ehs.entity.*;
import qc.module.ehs.mapper.EhsTaskExecMapper;
import qc.module.ehs.mapper.EhsTaskItemMapper;
import qc.module.ehs.repository.*;
import qc.module.platform.dto.uac.UacUserInfoDto;

import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 安全任务执行记录Service
 *
 * @author QuCheng Tech
 * @since 2024/11/13
 */
@Service
public class EhsTaskExecService {

    @Autowired
    private EhsTaskExecRepository repository;

    @Autowired
    private EhsTaskItemRepository taskItemRepository;

    @Autowired
    private EhsTaskInfoRepository taskInfoRepository;

    @Autowired
    private EhsTaskGroupRepository taskGroupRepository;

    @Autowired
    private EhsHazardIdentifyRepository hazardIdentifyRepository;

    @Autowired
    private EhsCheckRecordService checkRecordService;

    /**
     * 获取指定任务项的所有执行记录
     * 返回的结果按照执行起始时间降序排列；
     *
     * @param itemId 任务项ID
     * @return List<TaskExecuteInfoDto>
     * @author QuCheng Tech
     * @since 2024/11/13
     */
    public List<TaskExecuteInfoDto> getTaskItemExecutes(String itemId) {
        List<EhsTaskExec> ens = getTaskItemExecuteEntitys(itemId);
        if (CollectionUtils.isNotEmpty(ens)) {
            //如果执行记录不为空，获取任务项的信息
            EhsTaskItem itemEntity = taskItemRepository.selectById(itemId);
            List<TaskExecuteInfoDto> dtos = EhsTaskExecMapper.MAPPER.toDtoList(ens);
            for (TaskExecuteInfoDto dto : dtos) {
                if (Objects.nonNull(itemEntity)) {
                    dto.setItem(EhsTaskItemMapper.MAPPER.toDto(itemEntity));
                }
            }

            return dtos;
        }
        return null;
    }

    /***
     * 查询指定任务项的执行记录；按照实际执行的起始时间升序、截止时间升序；
     *
     * @param itemId 任务项ID
     * @return java.util.List<qc.module.ehs.entity.EhsTaskExec>
     * @author QuCheng Tech
     * @since 2025/3/10
     */
    public List<EhsTaskExec> getTaskItemExecuteEntitys(String itemId) {
        LambdaQueryWrapper<EhsTaskExec> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(EhsTaskExec::getItemid, itemId);
        //排序：按照实际执行的起始时间升序、截止时间升序；
        wrapper.orderByAsc(EhsTaskExec::getBegintm).orderByAsc(EhsTaskExec::getEndtm);

        return repository.selectList(wrapper);
    }

    /**
     * 获取指定任务分组的所有执行记录
     * <p>
     * 一个任务分组表示一个单元的任务集合，一个任务项表示一个单元一个执行周期（如一个月）的执行记录；
     * 需要将单元的所有执行记录进行展示时，需要根据任务分组进行查询；
     * 返回的结果按照执行起始时间降序排列；
     *
     * @param groupId 任务分组ID
     * @return List<TaskExecuteInfoDto>
     * @author QuCheng Tech
     * @since 2024/11/13
     */
    public List<TaskExecuteInfoDto> getTaskGroupExecutes(String groupId) {

        LambdaQueryWrapper<EhsTaskExec> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(EhsTaskExec::getGroupid, groupId)
                .orderByDesc(EhsTaskExec::getBegintm);
        List<EhsTaskExec> ens = repository.selectList(wrapper);
        if (CollectionUtils.isNotEmpty(ens)) {
            List<TaskExecuteInfoDto> dtos = EhsTaskExecMapper.MAPPER.toDtoList(ens);
            for (TaskExecuteInfoDto dto : dtos) {
                //获取指定任务项信息并返回
                EhsTaskItem itemEn = taskItemRepository.selectById(dto.getItemid());
                if (Objects.nonNull(itemEn)) {
                    dto.setItem(EhsTaskItemMapper.MAPPER.toDto(itemEn));
                }
            }

            return dtos;

        }
        return null;
    }

    /**
     * 获取指定执行记录
     *
     * @param id 执行记录ID
     * @return TaskExecuteInfoDto
     * @author QuCheng Tech
     * @since 2024/11/13
     */
    public TaskExecuteInfoDto get(String id) {

        EhsTaskExec en = repository.selectById(id);
        if (Objects.nonNull(en)) {
            TaskExecuteInfoDto dto = EhsTaskExecMapper.MAPPER.toDto(en);

            //获取指定任务项信息并返回
            EhsTaskItem itemEn = taskItemRepository.selectById(dto.getItemid());
            if (Objects.nonNull(itemEn)) {
                dto.setItem(EhsTaskItemMapper.MAPPER.toDto(itemEn));
            }

            //如果检查表记录ID不为空，根据执行记录ID和检查表记录ID查询对应的检查记录并返回
            if (StringUtils.isNotBlank(en.getCheckrecordid())) {
                CheckRecordDto checkRecordDto = checkRecordService.getByDataId(en.getExecid());
                if (Objects.nonNull(checkRecordDto)) {
                    dto.setCheckcontent(checkRecordDto.getContent());
                }
            }

            return dto;
        }
        return null;
    }

    /**
     * 新增执行记录
     * <p>
     * 要求任务项执行完成为false并且终止/取消为false；
     * 需要根据任务中是否需要确认对写入记录的是否确认状态进行设置；
     * 如不需要确认同时是否执行完成为true时，表示任务项已执行完成，在添加执行记录后自动设置对应任务项的执行完成为true；
     * 同时对实际执行次数、完成时间、辨识危险源次数、上报隐患次数、最新执行起止时间进行更新；
     *
     * @param dto 新增DTO
     * @return 成功返回null，失败返回错误或提示信息
     * @author QuCheng Tech
     * @since 2024/11/19
     */
    public String add(TaskExecuteAddDto dto, UacUserInfoDto userInfo) throws QCPromptException {
        //1.DTO有效性验证
        if (dto == null) return QCUnifyReturnValue.Warn("新增任务执行记录对象不能为空");
        if (StringUtils.isBlank(dto.getTaskid())) return QCUnifyReturnValue.Warn("任务ID不能为空");
        if (StringUtils.isBlank(dto.getGroupid())) return QCUnifyReturnValue.Warn("任务分组ID不能为空");
        if (StringUtils.isBlank(dto.getItemid())) return QCUnifyReturnValue.Warn("任务项ID不能为空");
        if (StringUtils.isBlank(dto.getCatname())) return QCUnifyReturnValue.Warn("任务分类名称不能为空");
        //if (dto.getTasktype() == null) return QCUnifyReturnValue.Warn("任务大类不能为空");
        if (StringUtils.isBlank(dto.getUnitid())) return QCUnifyReturnValue.Warn("单元ID不能为空");
        if (StringUtils.isBlank(dto.getUnitname())) return QCUnifyReturnValue.Warn("单元名称不能为空");
        if (StringUtils.isBlank(dto.getExecutor())) return QCUnifyReturnValue.Warn("执行人员不能为空");
        if (StringUtils.isBlank(dto.getExecutetmstr())) return QCUnifyReturnValue.Warn("执行时间不能为空");
        if (StringUtils.isBlank(dto.getBegintm())) return QCUnifyReturnValue.Warn("执行起始时间不能为空");
        if (StringUtils.isBlank(dto.getEndtm())) return QCUnifyReturnValue.Warn("执行截止时间不能为空");
        //2025-2-20，增加执行记录必须要有附件
        if (StringUtils.isBlank(dto.getExecattachment())) return QCUnifyReturnValue.Warn("执行附件不能为空");

        //执行起止时间处理
        Date beginDate = null;
        Date endDate = null;
        if (StringUtils.isNotBlank(dto.getBegintm())) {
            try {
                beginDate = DateUtil.parseDate(dto.getBegintm());
            } catch (Exception e) {
                // 时间转换错误，抛出自定义异常
                throw new QCPromptException("查询条件中的开始日期转换错误");
            }
        }
        if (StringUtils.isNotBlank(dto.getEndtm())) {
            try {
                endDate = DateUtil.parseDate(dto.getEndtm());
            } catch (Exception e) {
                // 时间转换错误，抛出自定义异常
                throw new QCPromptException("查询条件中的截止日期转换错误");
            }
        }
        //起始时间不能大于截止时间
        if (beginDate.after(endDate))
            throw new QCPromptException("起始时间不能大于截止时间。");
        //起始时间不能小于当前时间前三个月
        Date now = DateUtil.getNowDate();
        Date firstThreeMonthDate = DateUtil.addMonths(now, -3);
        if (beginDate.before(firstThreeMonthDate))
            throw new QCPromptException("起始时间不能小于当前时间的前三个月。");
        //截止时间不能大于当前时间
        if (endDate.after(now))
            throw new QCPromptException("截止时间不能大于当前时间。");
        dto.setBegintm(null);
        dto.setEndtm(null);

        //获取指定任务信息
        EhsTaskInfo taskInfo = taskInfoRepository.selectById(dto.getTaskid());
        if (Objects.isNull(taskInfo)) return QCUnifyReturnValue.Warn("指定任务信息不存在");

        //获取执行任务分组
        EhsTaskGroup group = taskGroupRepository.selectById(dto.getGroupid());
        if (Objects.isNull(group)) return QCUnifyReturnValue.Warn("指定任务分组信息不存在");

        //获取指定任务项信息
        EhsTaskItem item = taskItemRepository.selectById(dto.getItemid());
        if (Objects.isNull(item)) return QCUnifyReturnValue.Warn("指定任务项信息不存在");

        //要求任务项执行完成为false并且终止/取消为false
        if (item.getHasfinish() || item.getHasend())
            return QCUnifyReturnValue.Warn("任务项已经执行完成或者已经终止，不再进行新增执行记录操作。");

        //addDto转换为entity，设置默认值
        EhsTaskExec en = EhsTaskExecMapper.MAPPER.addDtoToEntity(dto);
        en.setExecid(IdentifierUtil.randomUUID());
        en.setBegintm(beginDate);
        en.setEndtm(endDate);
        en.setIntm(DateUtil.getNowDate());
        en.setInuserid(userInfo.getId());
        en.setInusername(userInfo.getName());

        //是否确认通过：需要根据任务中是否需要确认对写入记录的是否确认状态进行设置：默认需要确认通过
        en.setHasconfirm(false);
        //如不需要确认同时是否执行完成为true时，表示任务项已执行完成，在添加执行记录后自动设置对应任务项的执行完成为true；
        if (!taskInfo.getNeedconfirm() && dto.getHasexec()) {
            // 执行记录：是否确认通过为true，确认信息为空；
            en.setHasconfirm(true);
            //设置任务项为完成、完成时间
            item.setHasfinish(true);
        }

        //如果在传入检查表ID不为空时，新增检查记录，并将新增的任务执行记录中的检查表记录ID进行关联写入；
        if (StringUtils.isNotBlank(dto.getChecktableid()) && StringUtils.isNotBlank(dto.getCheckcontent())) {
            //如果检查表记录存在进行修改，不存在进行新增
            EhsCheckRecord checkRecord = new EhsCheckRecord();
            //不对检查表记录ID进行赋值，在保存检查表记录中自动判定为新增并生成ID
            //checkRecord.setRecordid(IdentifierUtil.randomUUID());
            checkRecord.setTableid(dto.getChecktableid());
            checkRecord.setDataid(en.getExecid());
            checkRecord.setUserid(userInfo.getId().toString());
            checkRecord.setContent(dto.getCheckcontent());

            CheckRecordSaveResultDto saveCheckRecordResult = checkRecordService.save(checkRecord);
            if (saveCheckRecordResult != null && saveCheckRecordResult.isSuccess() == true) {
                //保存检查表记录成功
                //将检查表记录ID赋值到执行记录对象信息中
                en.setCheckrecordid(saveCheckRecordResult.getRecordid());
            } else {
                //保存检查表记录失败，根据信息进行提示
                return QCUnifyReturnValue.Warn(saveCheckRecordResult.getMsg());
            }
        }

        //添加执行记录
        if (repository.insert(en) < 0x1) {
            return QCUnifyReturnValue.Warn("添加任务执行记录失败");
        }

        //修改任务项
        // 设置任务项：实际执行次数，最新执行起止时间
        //1.实际执行次数更新：根据任务项ID在任务执行记录表里查询记录总数作为任务项的实际执行次数；查询后需判断是否与任务项表中的当前实际执行次数一致，如果一致则无需进行操作；
        List<TaskExecuteInfoDto> executeInfoDtos = getTaskItemExecutes(item.getItemid());
        if (executeInfoDtos.size() != item.getExeccount()) {
            item.setExeccount(executeInfoDtos.size());
        }
        //2.最新执行开始时间、最新执行截止时间更新：根据任务项ID在任务执行记录表中查询指定任务项ID的执行记录集合，
        // 如果执行记录为空设置最新执行开始时间和最新执行截止时间为空，否则获取执行记录中执行起始时间最大的记录中的执行起始时间和执行截止时间进行设置；
        Date latestBeginTm = executeInfoDtos.stream().map(p -> DateUtil.parseDate(p.getBegintm())).max(Date::compareTo).get();
        Date latestEndTm = executeInfoDtos.stream().map(p -> DateUtil.parseDate(p.getEndtm())).max(Date::compareTo).get();
        if (latestBeginTm != null) item.setLatestexecbegintm(latestBeginTm);
        if (latestEndTm != null) item.setLatestexecendtm(latestEndTm);
        //在任务执行记录中选择未完成时不更新任务项的完成时间。
        if (dto.getHasexec()) {
            //3.任务是否执行完成、实际完成时间：使用当前新增的任务执行记录中的执行截止时间，如任务项表中已有实际完成时间并且大于当前任务执行记录中的执行截止时间则不需要进行更新；
            if (item.getExecendtm() == null) {
                item.setExecendtm(en.getEndtm());
            } else {
                if (item.getExecendtm().before(en.getEndtm())) {
                    item.setExecendtm(en.getEndtm());
                }
            }
        }

        taskItemRepository.updateById(item);

        //任务项的任务分组和任务的数据统计
        accountGroup(group);
        accountTask(taskInfo);

        return QCUnifyReturnValue.Success();
    }

    /**
     * 修改执行记录
     * <p>
     * 要求任务项执行完成为false并且终止/取消为false；
     * 需要根据任务中是否需要确认对写入记录的是否确认状态进行设置；
     * 如不需要确认同时是否执行完成为true时，表示任务项已执行完成，在修改执行记录后自动设置对应任务项的执行完成为true；
     * 同时对实际执行次数、完成时间、辨识危险源次数、上报隐患次数、最新执行起止时间进行更新；
     *
     * @param dto 修改DTO
     * @return 成功返回null，失败返回错误或提示信息
     * @author QuCheng Tech
     * @since 2024/11/19
     */
    public String update(TaskExecuteUpdateDto dto, UacUserInfoDto userInfo) throws QCPromptException {
        //1.DTO有效性验证
        if (dto == null) return QCUnifyReturnValue.Warn("新增任务执行记录对象不能为空");
        if (StringUtils.isBlank(dto.getExecid())) return QCUnifyReturnValue.Warn("执行记录ID不能为空");
        //根据执行记录ID获取Entity，判断是否有对应的记录存在
        EhsTaskExec existTaskExec = repository.selectById(dto.getExecid());
        if (existTaskExec == null)
            return QCUnifyReturnValue.Warn("指定的执行记录ID数据不存在");
        if (StringUtils.isBlank(dto.getUnitid())) return QCUnifyReturnValue.Warn("单元ID不能为空");
        if (StringUtils.isBlank(dto.getUnitname())) return QCUnifyReturnValue.Warn("单元名称不能为空");
        if (StringUtils.isBlank(dto.getExecutor())) return QCUnifyReturnValue.Warn("执行人员不能为空");
        if (StringUtils.isBlank(dto.getExecutetmstr())) return QCUnifyReturnValue.Warn("执行时间不能为空");
        if (StringUtils.isBlank(dto.getBegintm())) return QCUnifyReturnValue.Warn("执行起始时间不能为空");
        if (StringUtils.isBlank(dto.getEndtm())) return QCUnifyReturnValue.Warn("执行截止时间不能为空");
        //2025-2-20，增加执行记录必须要有附件
        if (StringUtils.isBlank(dto.getExecattachment())) return QCUnifyReturnValue.Warn("执行附件不能为空");

        EhsTaskExec exec = repository.selectById(dto.getExecid());
        if (Objects.isNull(exec)) return QCUnifyReturnValue.Warn("指定执行记录不存在");

        //获取指定任务信息
        EhsTaskInfo taskInfo = taskInfoRepository.selectById(exec.getTaskid());
        //获取执行任务分组
        EhsTaskGroup group = taskGroupRepository.selectById(exec.getGroupid());
        //获取指定任务项信息
        EhsTaskItem item = taskItemRepository.selectById(exec.getItemid());
        //要求任务项执行完成为false并且终止/取消为false
        if (item.getHasfinish() || item.getHasend())
            return QCUnifyReturnValue.Warn("任务项已经执行完成或者已经终止，不再进行修改执行记录操作。");

        //执行起止时间处理
        Date beginDate = null;
        Date endDate = null;
        if (StringUtils.isNotBlank(dto.getBegintm())) {
            try {
                beginDate = DateUtil.parseDate(dto.getBegintm());
            } catch (Exception e) {
                // 时间转换错误，抛出自定义异常
                throw new QCPromptException("查询条件中的开始日期转换错误");
            }
        }
        if (StringUtils.isNotBlank(dto.getEndtm())) {
            try {
                endDate = DateUtil.parseDate(dto.getEndtm());
            } catch (Exception e) {
                // 时间转换错误，抛出自定义异常
                throw new QCPromptException("查询条件中的截止日期转换错误");
            }
        }
        //起始时间不能大于截止时间
        if (beginDate.after(endDate))
            throw new QCPromptException("起始时间不能大于截止时间。");
        //起始时间不能小于当前时间前三个月
        Date now = DateUtil.getNowDate();
        Date firstThreeMonthDate = DateUtil.addMonths(now, -3);
        if (beginDate.before(firstThreeMonthDate))
            throw new QCPromptException("起始时间不能小于当前时间的前三个月。");
        //截止时间不能大于当前时间
        if (endDate.after(now))
            throw new QCPromptException("截止时间不能大于当前时间。");
        dto.setBegintm(null);
        dto.setEndtm(null);

        //addDto转换为entity，设置默认值
        EhsTaskExec en = EhsTaskExecMapper.MAPPER.toEntity(dto);
        en.setBegintm(beginDate);
        en.setEndtm(endDate);
        //修改执行记录时任务大类信息不修改，将Entity原有值进行赋值还原
        en.setTasktype(existTaskExec.getTasktype());

        //任务信息中设置为不需要确认，本次执行记录中为完成状态时：设置执行记录为确认，任务项为完成；
        if (taskInfo.getNeedconfirm().booleanValue() == false && dto.isHasexec() == true) {
            // 执行记录：是否确认通过为true，确认信息为空；
            en.setHasconfirm(true);
            item.setHasfinish(true);
        }

        //传入的检查表ID为空时表示执行记录不需要有检查表，也不需要有检查表记录；如果执行记录已有检查表记录需要删除；
        //传入的检查表ID不为空时表示执行记录需要有检查表；如有检查表记录ID不为空表示为修改已有检查表记录，否则为新增检查表记录
        if (StringUtils.isBlank(dto.getChecktableid())) {
            //如果传入的DTO中检查表ID为空，删除原有的检查表记录
            checkRecordService.deleteByDataId(dto.getExecid());
        } else {
            //需要有检查表记录，判断是否存在检查表记录（传入的检查表记录ID不为空并且数据实际在数据库中存在）
            String existCheckRecordId = null;
            if (StringUtils.isNotBlank(dto.getCheckrecordid())) {
                //判断检查表记录是否存在
                existCheckRecordId = dto.getCheckrecordid();
            }
            //如果检查表记录存在进行修改，不存在进行新增
            EhsCheckRecord checkRecord = new EhsCheckRecord();
            checkRecord.setRecordid(existCheckRecordId);
            checkRecord.setTableid(dto.getChecktableid());
            checkRecord.setDataid(dto.getExecid());
            checkRecord.setUserid(userInfo.getId().toString());
            checkRecord.setContent(dto.getCheckcontent());

            CheckRecordSaveResultDto saveCheckRecordResult = checkRecordService.save(checkRecord);
            if (saveCheckRecordResult != null && saveCheckRecordResult.isSuccess() == true) {
                //保存检查表记录成功
                //将检查表记录ID赋值到执行记录对象信息中
                en.setCheckrecordid(saveCheckRecordResult.getRecordid());
            } else {
                //保存检查表记录失败，根据信息进行提示
                return QCUnifyReturnValue.Warn(saveCheckRecordResult.getMsg());
            }
        }

        //修改执行记录
        repository.updateById(en);

        //修改任务项
        // 设置任务项：实际执行次数，最新执行起止时间
        //1.实际执行次数更新：根据任务项ID在任务执行记录表里查询记录总数作为任务项的实际执行次数；查询后需判断是否与任务项表中的当前实际执行次数一致，如果一致则无需进行操作；
        List<TaskExecuteInfoDto> executeInfoDtos = getTaskItemExecutes(item.getItemid());
        if (executeInfoDtos.size() != item.getExeccount()) {
            item.setExeccount(executeInfoDtos.size());
        }
        //2.最新执行开始时间、最新执行截止时间更新：根据任务项ID在任务执行记录表中查询指定任务项ID的执行记录集合，
        // 如果执行记录为空设置最新执行开始时间和最新执行截止时间为空，否则获取执行记录中执行起始时间最大的记录中的执行起始时间和执行截止时间进行设置；
        Date latestBeginTm = executeInfoDtos.stream().map(p -> DateUtil.parseDate(p.getBegintm())).max(Date::compareTo).get();
        Date latestEndTm = executeInfoDtos.stream().map(p -> DateUtil.parseDate(p.getEndtm())).max(Date::compareTo).get();
        if (latestBeginTm != null) item.setLatestexecbegintm(latestBeginTm);
        if (latestEndTm != null) item.setLatestexecendtm(latestEndTm);
        //在任务执行记录中选择未完成时不更新任务项的完成时间。
        if (dto.isHasexec() == true) {
            //3.任务是否执行完成、实际完成时间：使用当前新增的任务执行记录中的执行截止时间，如任务项表中已有实际完成时间并且大于当前任务执行记录中的执行截止时间则不需要进行更新；
            if (item.getExecendtm() == null) {
                item.setExecendtm(en.getEndtm());
            } else {
                if (item.getExecendtm().before(en.getEndtm())) {
                    item.setExecendtm(en.getEndtm());
                }
            }
        }

        taskItemRepository.updateById(item);

        //任务项的任务分组和任务的数据统计
        accountGroup(group);
        accountTask(taskInfo);

        return QCUnifyReturnValue.Success();
    }

    /**
     * 删除执行记录
     * <p>
     * 要求任务项执行完成为false并且终止/取消为false，同时执行记录的是否通过确认为false或确认时间为空（任务中设置不需要确认）；
     *
     * @param id 执行记录ID
     * @return 成功返回null，失败返回错误或提示信息
     * @author QuCheng Tech
     * @since 2024/11/19
     */
    public String delete(String id) {

        EhsTaskExec exec = repository.selectById(id);
        if (Objects.nonNull(exec)) {

            //获取指定任务项
            EhsTaskItem item = taskItemRepository.selectById(exec.getItemid());
            //要求任务项执行完成为false并且终止/取消为false
            if (item.getHasfinish() || item.getHasend())
                return QCUnifyReturnValue.Warn("任务项已经执行完成或者已经终止，不进行删除执行记录操作。");
            //同时执行记录的是否通过确认为false或确认时间为空（任务中设置不需要确认）；
            if (exec.getHasconfirm() && exec.getConfirmtm() != null)
                return QCUnifyReturnValue.Warn("执行记录已确认，不进行删除执行记录操作。");

            repository.deleteById(id);

            //修改任务项
            // 设置任务项：实际执行次数，最新执行起止时间
            //1.实际执行次数更新：根据任务项ID在任务执行记录表里查询记录总数作为任务项的实际执行次数；查询后需判断是否与任务项表中的当前实际执行次数一致，如果一致则无需进行操作；
            List<TaskExecuteInfoDto> executeInfoDtos = getTaskItemExecutes(item.getItemid());
            if (executeInfoDtos == null) {
                item.setExeccount(0x0);
            } else {
                if (executeInfoDtos.size() != item.getExeccount()) {
                    item.setExeccount(executeInfoDtos.size());
                }
                //2.最新执行开始时间、最新执行截止时间更新：根据任务项ID在任务执行记录表中查询指定任务项ID的执行记录集合，
                // 如果执行记录为空设置最新执行开始时间和最新执行截止时间为空，否则获取执行记录中执行起始时间最大的记录中的执行起始时间和执行截止时间进行设置；
                Date latestBeginTm = executeInfoDtos.stream().map(p -> DateUtil.parseDate(p.getBegintm())).max(Date::compareTo).get();
                Date latestEndTm = executeInfoDtos.stream().map(p -> DateUtil.parseDate(p.getEndtm())).max(Date::compareTo).get();
                if (latestBeginTm != null) item.setLatestexecbegintm(latestBeginTm);
                if (latestEndTm != null) item.setLatestexecendtm(latestEndTm);
            }

            taskItemRepository.updateById(item);
            //任务项的任务分组和任务的数据统计
            //获取执行任务分组
            EhsTaskGroup group = taskGroupRepository.selectById(exec.getGroupid());
            //获取指定任务信息
            EhsTaskInfo taskInfo = taskInfoRepository.selectById(exec.getTaskid());
            accountGroup(group);
            accountTask(taskInfo);
        }

        return QCUnifyReturnValue.Success();
    }

    /**
     * 确认执行记录
     * <p>
     * 要求执行记录的是否确认为false；
     * 在确认操作后如执行记录中的执行是否完成为true，自动设置任务项的执行完成为true；同时对实际执行次数、完成时间、辨识危险源次数、上报隐患次数、最新执行起止时间进行更新；
     *
     * @param dto 确认信息
     * @return 成功返回null，失败返回错误或提示信息
     * @author QuCheng Tech
     * @since 2024/11/19
     */
    public String confirm(TaskExecuteConfirmDto dto, UacUserInfoDto userInfo) {
        if (dto == null) return QCUnifyReturnValue.Warn("确认信息不能为空");
        if (StringUtils.isBlank(dto.getExecid())) return QCUnifyReturnValue.Warn("执行记录ID不能为空");

        EhsTaskExec exec = repository.selectById(dto.getExecid());
        if (Objects.isNull(exec)) return QCUnifyReturnValue.Warn("执行记录信息不存在。");

        //要求执行记录的是否确认为false
        if (exec.getHasconfirm()) return QCUnifyReturnValue.Warn("执行记录已确认，无需重复操作。");

        //修改执行记录确认信息
        exec.setHasconfirm(true);
        exec.setConfirmtm(DateUtil.getNowDate());
        exec.setConfirmuserid(userInfo.getId());
        exec.setConfirmusername(userInfo.getName());
        exec.setConfirmsign(dto.getConfirmsign());
        exec.setConfirmdescription(dto.getConfirmdescription());
        exec.setConfirmattachment(dto.getConfirmattachment());
        repository.updateById(exec);

        //修改任务项：任务是否执行完成，实际完成时间
        if (exec.getHasexec()) {
            ////获取指定任务项信息
            EhsTaskItem item = taskItemRepository.selectById(exec.getItemid());
            //任务是否执行完成、实际完成时间：使用当前新增的任务执行记录中的执行截止时间，
            // 如任务项表中已有实际完成时间并且大于当前任务执行记录中的执行截止时间则不需要进行更新；
            item.setHasfinish(true);
            if (item.getExecendtm() == null) {
                item.setExecendtm(exec.getEndtm());
            } else {
                if (item.getExecendtm().before(exec.getEndtm())) {
                    item.setExecendtm(exec.getEndtm());
                }
            }
            taskItemRepository.updateById(item);
        }

        return QCUnifyReturnValue.Success();
    }

    /**
     * 查询执行记录
     * <p>
     * 用于查询指定单元或指定危险源的任务执行记录；返回的数据按执行开始时间升序排列；
     *
     * @param condition 查询条件
     * @return List<TaskExecuteInfoDto>
     * @author QuCheng Tech
     * @since 2024/12/3
     */
    public List<TaskExecuteInfoDto> query(TaskExecuteQueryConditionDto condition) throws QCPromptException {
        //1.查询条件有效性验证
        if (condition == null)
            throw new QCPromptException("查询执行记录的查询条件不能为空");
        if (StringUtils.isBlank(condition.getOrgcode()))
            throw new QCPromptException("查询执行记录的组织机构代码不能为空");
        if (StringUtils.isBlank(condition.getBegintm()))
            throw new QCPromptException("查询执行记录的开始时间不能为空");
        if (StringUtils.isBlank(condition.getEndtm()))
            throw new QCPromptException("查询执行记录的截止时间不能为空");

        //2.查询时间转换处理
        Date beginDate = null;
        Date endDate = null;
        if (StringUtils.isNotBlank(condition.getBegintm())) {
            try {
                beginDate = DateUtil.parseDate(condition.getBegintm());
            } catch (Exception e) {
                // 时间转换错误，抛出自定义异常
                throw new QCPromptException("查询条件中的开始日期转换错误");
            }
        }
        if (StringUtils.isNotBlank(condition.getEndtm())) {
            try {
                endDate = DateUtil.parseDate(condition.getEndtm());
            } catch (Exception e) {
                // 时间转换错误，抛出自定义异常
                throw new QCPromptException("查询条件中的截止日期转换错误");
            }
        }
        if (beginDate.after(endDate))
            throw new QCPromptException("开始时间不能大于截止时间");

        //3.根据查询条件先过滤任务项
        LambdaQueryWrapper<EhsTaskItem> itemWrapper = new LambdaQueryWrapper<>();
        itemWrapper.eq(EhsTaskItem::getOrgcode, condition.getOrgcode());
        if (StringUtils.isNotBlank(condition.getKeywords())) {
            itemWrapper.and(q -> {
                q.like(EhsTaskItem::getUnitname, condition.getKeywords()).or()
                        .like(EhsTaskItem::getFacilityname, condition.getKeywords()).or()
                        .like(EhsTaskItem::getHazardname, condition.getKeywords()).or()
                        .like(EhsTaskItem::getResdeptname, condition.getKeywords()).or()
                        .like(EhsTaskItem::getResusername1, condition.getKeywords()).or()
                        .like(EhsTaskItem::getResusername2, condition.getKeywords());
            });
        }
        if (StringUtils.isNotBlank(condition.getUnitid())) {
            itemWrapper.eq(EhsTaskItem::getUnitid, condition.getUnitid());
        }
        if (StringUtils.isNotBlank(condition.getHazardid())) {
            itemWrapper.eq(EhsTaskItem::getHazardid, condition.getHazardid());
        }
        if (StringUtils.isNotBlank(condition.getFacilityid())) {
            itemWrapper.eq(EhsTaskItem::getFacilityid, condition.getFacilityid());
        }
        List<EhsTaskItem> items = taskItemRepository.selectList(itemWrapper);
        if (CollectionUtils.isEmpty(items)) return null;


        //4.根据过滤后的任务项ID集合与查询时间段查询任务项执行记录
        List<String> itemIds = items.stream().map(EhsTaskItem::getItemid).collect(Collectors.toList());
        LambdaQueryWrapper<EhsTaskExec> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(EhsTaskExec::getItemid, itemIds);
        Date finalBeginDate = beginDate;
        Date finalEndDate = endDate;
        wrapper.and(q -> q.ge(EhsTaskExec::getBegintm, finalBeginDate).le(EhsTaskExec::getEndtm, finalEndDate));
        //按执行开始时间升序
        wrapper.orderByAsc(EhsTaskExec::getBegintm);
        List<EhsTaskExec> ens = repository.selectList(wrapper);
        if (CollectionUtils.isNotEmpty(ens)) {
            List<TaskExecuteInfoDto> dtos = EhsTaskExecMapper.MAPPER.toDtoList(ens);
            for (TaskExecuteInfoDto dto : dtos) {
                //获取指定任务项信息并返回
                EhsTaskItem itemEn = items.stream().filter(item -> item.getItemid().equals(dto.getItemid())).findAny().orElse(null);
                if (Objects.nonNull(itemEn)) {
                    dto.setItem(EhsTaskItemMapper.MAPPER.toDto(itemEn));
                }
            }

            return dtos;
        }

        return null;
    }

    /**
     * 获取指定任务的所有执行记录
     * <p>
     * 查询指定任务的所有执行记录集合；
     * 不显示任务分组和任务项，所有执行记录以表格方式显示；
     * 执行记录按照执行起始时间升序返回；
     *
     * @param taskId 任务ID
     * @return List<TaskExecuteInfoDto>
     * @author QuCheng Tech
     * @since 2024/11/18
     */
    public List<TaskExecuteInfoDto> getTaskExecutes(String taskId) {
        LambdaQueryWrapper<EhsTaskExec> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(EhsTaskExec::getTaskid, taskId)
                .orderByAsc(EhsTaskExec::getBegintm);
        List<EhsTaskExec> ens = repository.selectList(wrapper);

        if (CollectionUtils.isNotEmpty(ens)) {
            List<TaskExecuteInfoDto> dtos = EhsTaskExecMapper.MAPPER.toDtoList(ens);
            for (TaskExecuteInfoDto dto : dtos) {
                //获取指定任务项信息并返回
                EhsTaskItem itemEn = taskItemRepository.selectById(dto.getItemid());
                if (Objects.nonNull(itemEn)) {
                    dto.setItem(EhsTaskItemMapper.MAPPER.toDto(itemEn));
                }
            }

            return dtos;
        }

        return null;
    }

    /**
     * 统计指定分组中的数量
     *
     * @param group 分组信息
     * @return 成功返回null，失败返回错误或提示信息
     * @author QuChengTech
     * @since 2024/11/19
     */
    public String accountGroup(EhsTaskGroup group) {
        //获取指定分组的任务项
        LambdaQueryWrapper<EhsTaskItem> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(EhsTaskItem::getGroupid, group.getGroupid());
        wrapper.orderByDesc(EhsTaskItem::getLatestexecbegintm);
        List<EhsTaskItem> ens = taskItemRepository.selectList(wrapper);
        int execCount = 0x0;
        int identifyCount = 0x0;
        int troubleCount = 0x0;
        if (CollectionUtils.isNotEmpty(ens)) {
            for (EhsTaskItem item : ens) {
                execCount += item.getExeccount();
                identifyCount += item.getExecidentifycount();
                troubleCount += item.getExectroublecount();
            }
            group.setLatestexectm(ens.get(0).getPlantmstr());//最新执行周期：取集合中按最新执行开始时间降序排列后第一条记录中的计划时间周期文字；
            //最新执行完成时间：在任务项表中同时且实际完成时间不为空的任务项集合，取集合中按最新执行开始时间降序排列后第一条记录中的实际完成时间；
            //获取任务项实际完成实际不为空的集合
            List<EhsTaskItem> execendTmNotNull = ens.stream().filter(p -> p.getExecendtm() != null).collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(execendTmNotNull)) {
                group.setLatestexecendtm(execendTmNotNull.get(0).getExecendtm());
            }
        }

        group.setExeccount(execCount);
        group.setExecidentifycount(identifyCount);
        group.setExectroublecount(troubleCount);

        taskGroupRepository.updateById(group);
        return QCUnifyReturnValue.Success();
    }

    /**
     * 统计指定任务中的数量
     *
     * @param taskInfo 任务信息
     * @return 成功返回null，失败返回错误或提示信息
     * @author QuChengTech
     * @since 2024/11/19
     */
    public String accountTask(EhsTaskInfo taskInfo) {
        //获取指定任务的所有分组
        LambdaQueryWrapper<EhsTaskGroup> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(EhsTaskGroup::getTaskid, taskInfo.getTaskid());
        List<EhsTaskGroup> ens = taskGroupRepository.selectList(wrapper);
        int execCount = 0x0;
        int identifyCount = 0x0;
        int troubleCount = 0x0;
        if (CollectionUtils.isNotEmpty(ens)) {
            for (EhsTaskGroup group : ens) {
                execCount += group.getExeccount();
                identifyCount += group.getExecidentifycount();
                troubleCount += group.getExectroublecount();
            }
        }

        taskInfo.setExeccount(execCount);
        taskInfo.setExecidentifycount(identifyCount);
        taskInfo.setExectroublecount(troubleCount);
        taskInfoRepository.updateById(taskInfo);
        return QCUnifyReturnValue.Success();
    }
}
